package com.acme.bankapp.network;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Properties;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Console bank initiator.
 * @author Alekov Andrey
 *
 */
public class BankInitiator {
	final static Logger logger = LoggerFactory.getLogger(BankInitiator.class);
	private Properties settings;

	/**
	 * Constructor
	 */
	BankInitiator(Properties appSettings) {
		this.settings = appSettings;
	}

	void run() {
		try (Socket requestSocket = new Socket(settings.getProperty("Interface"), 
				Integer.parseInt(settings.getProperty("Port")))) {
			logger.info("Connected to + "
					+ settings.getProperty("Interface") +" in port "
					+ settings.getProperty("Port"));
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			ObjectOutputStream outStream = new ObjectOutputStream(requestSocket.getOutputStream());
			ObjectInputStream inStream = new ObjectInputStream(requestSocket.getInputStream());
			boolean isExit = false;
			do {
				try {
					logger.info("CMD>");
					String input = reader.readLine();
					switch (input) {
						case "EXIT":
							outStream.writeObject(new Message("EXIT", ""));
							outStream.flush();
							isExit = true;
							break;
						default:
							try {
								String[] pair = input.split(Pattern.quote("="));
								Message messageOut = new Message(pair[0], pair[1]);
								outStream.writeObject(messageOut);
								outStream.flush();
								logger.info(">> " + messageOut.toString());
								// TODO: Rewrite to separate handler.
								Message messageIn = (Message) inStream.readObject();
								logger.info("<< " + messageIn.toString());
							} catch(ArrayIndexOutOfBoundsException e){
								logger.error("Invalid command command. "
										+ "Use CMD=VALUE");
							}
							break;
						}
				} catch (ClassNotFoundException e) {
					logger.error("Unknown message object!");
					e.printStackTrace();
				}
			} while (!isExit);
		} catch (UnknownHostException e) {
			logger.error("You are trying to connect to an unknown host!");
			e.printStackTrace();
		} catch (SocketException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}

	public static void main(final String args[]) {
		Properties settings = new Properties();
		try (FileInputStream in = new FileInputStream("server.settings")){
			settings.load(in);
			in.close();
		} catch (IOException e) {
			logger.error("Failed to loading settings");
			e.printStackTrace();
		}
		BankInitiator client = new BankInitiator(settings);
		client.run();
	}

}
